package com.xiaomaoguai.fcp.pre.kepler.router.rpc.server.servlet.core;

import com.xiaomaoguai.fcp.pre.kepler.router.rpc.server.servlet.response.NettyHttpServletResponse;
import com.xiaomaoguai.fcp.pre.kepler.router.rpc.server.servlet.response.SendResponse;
import com.xiaomaoguai.fcp.pre.kepler.router.utils.SerializeUtils;
import io.netty.handler.codec.http.HttpResponseStatus;
import org.apache.commons.javaflow.api.Continuation;
import org.apache.commons.javaflow.api.continuable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;


public abstract class Continuable implements Runnable {

	private final static Logger log = LoggerFactory.getLogger(Continuable.class);

	protected volatile Continuation c;

	protected NettyHttpServletResponse response;

	public NettyHttpServletResponse getResponse() {
		return response;
	}

	public void setResponse(NettyHttpServletResponse response) {
		this.response = response;
	}

	public Continuation getC() {
		return c;
	}

	public void setC(Continuation c) {
		this.c = c;
	}

	@continuable
	@Override
	public void run() {
		try {
			Object data = process();
			sendResult(data);
		} catch (Exception e) {
			log.error("{}  process error", response.getCtx(), e);
			try {
				SendResponse.sendError(response.getCtx(), HttpResponseStatus.BAD_GATEWAY);
			} catch (IOException e1) {
			}
		}
	}

	@continuable
	protected abstract Object process();

	protected void sendResult(Object result) throws IOException {
		byte[] resp = SerializeUtils.encode(result);
		SendResponse.resp(response.getCtx(), response, resp);
	}

	public Continuation resume(Object data) {
		while (true) {
			if (c != null) {
				return c.resume(data);
			}
			Thread.yield();
		}
	}

}
